package starfire.gui.defaultModelAndRenderer;

import java.io.*;
import java.util.*;

import javax.swing.*;
import javax.swing.filechooser.*;

import sun.awt.shell.*;

/**
 * <p>Title: </p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2003</p>
 * <p>Company: </p>
 * @author zzzhc.starfire@gmail.com
 * @version 1.0
 */

public class LocaleListComboModel
    extends AbstractListModel
    implements ComboBoxModel {
  int[] depths = null;
  Vector directories = new Vector();
  File selectedDirectory = null;

  public LocaleListComboModel() {
    FileSystemView fsv = FileSystemView.getFileSystemView();
    File directory = fsv.getHomeDirectory();
    addItem(directory);
  }

  public LocaleListComboModel(File directory) {
    addItem(directory);
  }

  private void addItem(File directory) {
    directories.clear();
    File[] baseFolders;
    baseFolders = (File[]) ShellFolder.get("fileChooserComboBoxFolders");
    directories.addAll(Arrays.asList(baseFolders));
    if (directory == null) {
      return;
    }

// Get the canonical (full) path. This has the side
// benefit of removing extraneous chars from the path,
// for example /foo/bar/ becomes /foo/bar
    File canonical = null;
    try {
      canonical = directory.getCanonicalFile();
    }
    catch (IOException e) {
      // Maybe drive is not ready. Can't abort here.
      canonical = directory;
    }

// create File instances of each directory leading up to the top
    try {
      File sf = ShellFolder.getShellFolder(canonical);
      File f = sf;
      Vector path = new Vector(10);
      do {
        path.addElement(f);
      }
      while ( (f = f.getParentFile()) != null);

      int pathCount = path.size();
      // Insert chain at appropriate place in vector
      for (int i = 0; i < pathCount; i++) {
        f = (File) path.get(i);
        if (directories.contains(f)) {
          int topIndex = directories.indexOf(f);
          for (int j = i - 1; j >= 0; j--) {
            directories.insertElementAt(path.get(j), topIndex + i - j);
          }
          break;
        }
      }
      calculateDepths();
      setSelectedItem(sf);
    }
    catch (FileNotFoundException ex) {
      calculateDepths();
    }
  }

  private void calculateDepths() {
    depths = new int[directories.size()];
    for (int i = 0; i < depths.length; i++) {
      File dir = (File) directories.get(i);
      File parent = dir.getParentFile();
      depths[i] = 0;
      if (parent != null) {
        for (int j = i - 1; j >= 0; j--) {
          if (parent.equals( (File) directories.get(j))) {
            depths[i] = depths[j] + 1;
            break;
          }
        }
      }
    }
  }

  public int getDepth(int index) {
    return (depths != null && index >= 0 && index < depths.length) ?
        depths[index] : 0;
  }

  public int getSize() {
    return directories.size();
  }

  public Object getElementAt(int index) {
    return directories.get(index);
  }

  public void setSelectedItem(Object obj) {
    this.selectedDirectory = (File) obj;
    this.fireContentsChanged(obj, -1, -1);
  }

  public Object getSelectedItem() {
    return selectedDirectory;
  }
}
